<?php

namespace app\admin\controller\scanwork;

use app\common\controller\Backend;
use think\Db;
use Exception;
use think\exception\PDOException;
use think\exception\ValidateException;

/**
 * 服务通知管理
 *
 * @icon fa fa-bell
 * @remark 管理小程序服务通知
 */
class ServiceNotification extends Backend
{
    protected $noNeedLogin = [];
    protected $noNeedRight = ['*'];

    public function _initialize()
    {
        parent::_initialize();
    }

    /**
     * 发送任务分配通知
     */
    public function sendAllocationNotice()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post();
            
            try {
                $allocationId = $params['allocation_id'] ?? 0;
                if (!$allocationId) {
                    throw new Exception('分工ID不能为空');
                }

                // 获取分工信息
                $allocation = \app\admin\model\scanwork\Allocation::with(['order', 'model.product', 'process', 'user'])
                    ->find($allocationId);
                
                if (!$allocation) {
                    throw new Exception('分工记录不存在');
                }

                // 获取用户openid
                $user = \app\common\model\User::find($allocation->user_id);
                if (!$user || !$user->openid) {
                    throw new Exception('用户openid不存在');
                }

                // 检查用户是否授权了服务通知
                $hasAuth = $this->checkUserNotificationAuth($allocation->user_id, 'OPENTM400000000');
                if (!$hasAuth) {
                    throw new Exception('用户未授权服务通知');
                }

                // 发送服务通知
                $result = $this->sendWechatNotification(
                    $user->openid,
                    'OPENTM400000000', // 任务分配通知模板ID
                    [
                        'keyword1' => ['value' => $allocation->model->product->name . '-' . $allocation->model->name],
                        'keyword2' => ['value' => date('Y-m-d H:i:s')],
                        'keyword3' => ['value' => $allocation->process->name . '工序'],
                        'keyword4' => ['value' => $allocation->quantity . '件']
                    ],
                    'pages/tasks/tasks'
                );

                if ($result['errcode'] == 0) {
                    // 记录发送日志
                    $this->logNotification($allocation->user_id, 'allocation', $allocationId, 'success');
                    
                    return json(['code' => 1, 'msg' => '通知发送成功']);
                } else {
                    // 记录发送失败日志
                    $this->logNotification($allocation->user_id, 'allocation', $allocationId, 'failed', $result['errmsg']);
                    
                    throw new Exception('通知发送失败：' . $result['errmsg']);
                }

            } catch (Exception $e) {
                return json(['code' => 0, 'msg' => $e->getMessage()]);
            }
        }
        
        return json(['code' => 0, 'msg' => '请求方式错误']);
    }

    /**
     * 发送审核结果通知
     */
    public function sendAuditNotice()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post();
            
            try {
                $reportId = $params['report_id'] ?? 0;
                $auditResult = $params['audit_result'] ?? '';
                $auditComment = $params['audit_comment'] ?? '';
                
                if (!$reportId) {
                    throw new Exception('报工记录ID不能为空');
                }

                // 获取报工信息
                $report = \app\admin\model\scanwork\Report::with(['allocation.user'])
                    ->find($reportId);
                
                if (!$report) {
                    throw new Exception('报工记录不存在');
                }

                // 获取用户openid
                $user = $report->allocation->user;
                if (!$user || !$user->openid) {
                    throw new Exception('用户openid不存在');
                }

                // 检查用户是否授权了服务通知
                $hasAuth = $this->checkUserNotificationAuth($user->id, 'OPENTM400000001');
                if (!$hasAuth) {
                    throw new Exception('用户未授权服务通知');
                }

                // 发送服务通知
                $result = $this->sendWechatNotification(
                    $user->openid,
                    'OPENTM400000001', // 审核通知模板ID
                    [
                        'keyword1' => ['value' => $auditResult],
                        'keyword2' => ['value' => date('Y-m-d H:i:s')],
                        'keyword3' => ['value' => $auditComment]
                    ],
                    'pages/records/records'
                );

                if ($result['errcode'] == 0) {
                    // 记录发送日志
                    $this->logNotification($user->id, 'audit', $reportId, 'success');
                    
                    return json(['code' => 1, 'msg' => '通知发送成功']);
                } else {
                    // 记录发送失败日志
                    $this->logNotification($user->id, 'audit', $reportId, 'failed', $result['errmsg']);
                    
                    throw new Exception('通知发送失败：' . $result['errmsg']);
                }

            } catch (Exception $e) {
                return json(['code' => 0, 'msg' => $e->getMessage()]);
            }
        }
        
        return json(['code' => 0, 'msg' => '请求方式错误']);
    }

    /**
     * 发送系统通知
     */
    public function sendSystemNotice()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post();
            
            try {
                $userId = $params['user_id'] ?? 0;
                $noticeType = $params['notice_type'] ?? '';
                $noticeContent = $params['notice_content'] ?? '';
                
                if (!$userId || !$noticeType || !$noticeContent) {
                    throw new Exception('参数不完整');
                }

                // 获取用户openid
                $user = \app\common\model\User::find($userId);
                if (!$user || !$user->openid) {
                    throw new Exception('用户openid不存在');
                }

                // 检查用户是否授权了服务通知
                $hasAuth = $this->checkUserNotificationAuth($userId, 'OPENTM400000002');
                if (!$hasAuth) {
                    throw new Exception('用户未授权服务通知');
                }

                // 发送服务通知
                $result = $this->sendWechatNotification(
                    $user->openid,
                    'OPENTM400000002', // 系统通知模板ID
                    [
                        'keyword1' => ['value' => $noticeType],
                        'keyword2' => ['value' => $noticeContent],
                        'keyword3' => ['value' => date('Y-m-d H:i:s')]
                    ],
                    'pages/index/index'
                );

                if ($result['errcode'] == 0) {
                    // 记录发送日志
                    $this->logNotification($userId, 'system', 0, 'success');
                    
                    return json(['code' => 1, 'msg' => '通知发送成功']);
                } else {
                    // 记录发送失败日志
                    $this->logNotification($userId, 'system', 0, 'failed', $result['errmsg']);
                    
                    throw new Exception('通知发送失败：' . $result['errmsg']);
                }

            } catch (Exception $e) {
                return json(['code' => 0, 'msg' => $e->getMessage()]);
            }
        }
        
        return json(['code' => 0, 'msg' => '请求方式错误']);
    }

    /**
     * 更新用户服务通知授权状态
     */
    public function updateServiceNotificationStatus()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post();
            
            try {
                $userId = $this->auth->id;
                $subscribeStatus = $params['subscribe_status'] ?? [];
                
                if (empty($subscribeStatus)) {
                    throw new Exception('授权状态不能为空');
                }

                // 保存用户授权状态
                foreach ($subscribeStatus as $templateId => $status) {
                    $data = [
                        'user_id' => $userId,
                        'template_id' => $templateId,
                        'status' => $status ? 1 : 0,
                        'updated_at' => date('Y-m-d H:i:s')
                    ];
                    
                    // 检查是否已存在记录
                    $existing = Db::name('user_notification_auth')->where([
                        'user_id' => $userId,
                        'template_id' => $templateId
                    ])->find();
                    
                    if ($existing) {
                        // 更新现有记录
                        Db::name('user_notification_auth')->where([
                            'user_id' => $userId,
                            'template_id' => $templateId
                        ])->update($data);
                    } else {
                        // 插入新记录
                        $data['created_at'] = date('Y-m-d H:i:s');
                        Db::name('user_notification_auth')->insert($data);
                    }
                }
                
                return json(['code' => 1, 'msg' => '授权状态更新成功']);

            } catch (Exception $e) {
                return json(['code' => 0, 'msg' => $e->getMessage()]);
            }
        }
        
        return json(['code' => 0, 'msg' => '请求方式错误']);
    }

    /**
     * 检查用户是否授权了指定模板的通知
     */
    private function checkUserNotificationAuth($userId, $templateId)
    {
        $auth = Db::name('user_notification_auth')->where([
            'user_id' => $userId,
            'template_id' => $templateId,
            'status' => 1
        ])->find();
        
        return !empty($auth);
    }

    /**
     * 发送微信服务通知
     */
    private function sendWechatNotification($openid, $templateId, $data, $page = 'pages/index/index')
    {
        // 获取小程序配置
        $appId = config('wechat.mini_program.app_id');
        $appSecret = config('wechat.mini_program.app_secret');
        
        if (!$appId || !$appSecret) {
            throw new Exception('小程序配置不完整');
        }

        // 获取access_token
        $accessToken = $this->getAccessToken($appId, $appSecret);
        
        // 发送服务通知
        $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={$accessToken}";
        
        $postData = [
            'touser' => $openid,
            'template_id' => $templateId,
            'page' => $page,
            'data' => $data
        ];
        
        $result = $this->httpPost($url, json_encode($postData, JSON_UNESCAPED_UNICODE));
        $response = json_decode($result, true);
        
        return $response ?: ['errcode' => -1, 'errmsg' => '请求失败'];
    }

    /**
     * 获取微信access_token
     */
    private function getAccessToken($appId, $appSecret)
    {
        // 先从缓存获取
        $cacheKey = 'wechat_access_token_' . $appId;
        $accessToken = cache($cacheKey);
        
        if ($accessToken) {
            return $accessToken;
        }
        
        // 重新获取access_token
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";
        $result = $this->httpGet($url);
        $response = json_decode($result, true);
        
        if (isset($response['access_token'])) {
            // 缓存access_token（有效期7200秒，提前200秒过期）
            cache($cacheKey, $response['access_token'], 7000);
            return $response['access_token'];
        } else {
            throw new Exception('获取access_token失败：' . ($response['errmsg'] ?? '未知错误'));
        }
    }

    /**
     * HTTP GET请求
     */
    private function httpGet($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }

    /**
     * HTTP POST请求
     */
    private function httpPost($url, $data)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($data)
        ]);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }

    /**
     * 记录通知发送日志
     */
    private function logNotification($userId, $type, $relatedId, $status, $message = '')
    {
        $data = [
            'user_id' => $userId,
            'type' => $type,
            'related_id' => $relatedId,
            'status' => $status,
            'message' => $message,
            'created_at' => date('Y-m-d H:i:s')
        ];
        
        Db::name('notification_logs')->insert($data);
    }
}
